home *** CD-ROM | disk | FTP | other *** search
- Path: news.daimi.aau.dk!liborius
- From: liborius@daimi.aau.dk (Per Liboriussen)
- Newsgroups: comp.sys.amiga.programmer
- Subject: 3 bugs in SAS/C v. 6.56
- Date: 23 Feb 1996 09:04:44 GMT
- Organization: DAIMI, Computer Science Dept. at Aarhus University
- Message-ID: <4gjvvc$a3t@gjallar.daimi.aau.dk>
- NNTP-Posting-Host: lire.daimi.aau.dk
- Keywords: SAS/C,bug
-
- I have found 3 bugs in SAS/C version 6.56: Two cases of generating bad code,
- and one case of refusing to compile a correct program. Below are descriptions
- of the problems, including the smallest programs I have been able to find
- which shows the bugs, and the commandlines used to compile. Hopefully someone
- from SAS reads this (and puts out a 6.57 patch ;-) ).
-
- -------------------------------------------------------------------------
- Number 1:
-
- The following program produces the output "bad" instead of "ok" as it should.
-
- ------------------------------
- #include <stdio.h>
-
- int main(void)
- {
- unsigned short a = 0xffff, b = 0xffff;
-
- if ((a | b) > 0x7fff) {
- printf("ok\n");
- } else {
- printf("bad\n");
- }
- return 0;
- }
- ------------------------------
-
- This is the commandline and compiler output:
- 1> sc RESETOPTIONS ushort.c LINK
- SAS/C Amiga Compiler 6.56
- Copyright (c) 1988-1995 SAS Institute Inc.
- Slink - Version 6.56
- Copyright (c) 1988-1995 SAS Institute, Inc. All Rights Reserved.
-
-
- SLINK Complete - Maximum code size = 5392 ($00001510) bytes
-
- Final output file size = 5408 ($00001520) bytes
- 1>
-
- The bitwise operation in the if-expression is important. If it is written
- simply as "if (a > 0x...)" it works correctly.
-
- -------------------------------------------------------------------------
- Number 2:
-
- This program causes the compiler to choke:
-
- ------------------------------
- union un {
- const char *cp;
- char *p;
- };
-
- const char *foo(union un *unp, int n)
- {
- /* The following line is important. It seems that a conditional
- expression involving both unp->cp and unp->p must appear somewhere
- in order to trigger the bug. */
- return (n ? unp->p : unp->cp);
- }
-
- void bar(union un *unp)
- {
- *(unp->p) = '7';
- }
- ------------------------------
-
- The compiler output:
- 1> sc RESETOPTIONS const.c
- SAS/C Amiga Compiler 6.56
- Copyright (c) 1988-1995 SAS Institute Inc.
-
- ====================
- *(unp->p) = '7';
- const.c 16 Error 99: attempt to change a const value
- 1>
-
- As the comment in foo() indicates, the conditional expression is important.
- If it is removed, or even if foo() is rewritten to return a char and the line
- changed to "return (n ? *unp->p : *unp->cp);", the bug goes away.
-
- -------------------------------------------------------------------------
- Number 3:
-
- At least this one shows itself more clearly and dramatically than number 1. ;-)
-
- ------------------------------
- void foo(float);
- void bar(float);
-
- void foo(f)
- float f;
- {
- bar(f);
- }
- ------------------------------
-
- When compiled with
- 1> sc RESETOPTIONS PARAMETERS=REGISTER NOSTACKCHECK float.c
- SAS/C Amiga Compiler 6.56
- Copyright (c) 1988-1995 SAS Institute Inc.
- 1>
-
- it produces the following assembler output: (the NOSTACKCHECK option is not
- important, it is just to reduce the clutter in the asm. file)
-
- ------------------------------
- SAS AMIGA 680x0OBJ Module Disassembler 6.55
- Copyright ⌐ 1995 SAS Institute, Inc.
-
-
- Amiga Object File Loader V1.00
- 68000 Instruction Set
-
- EXTERNAL DEFINITIONS
-
- @foo 0000-00
-
- SECTION 00 "text" 00000010 BYTES
- | 0000 594F SUBQ.W #4,A7
- | 0002 48D7 0003 MOVEM.L D0-D1,(A7)
- | 0006 2017 MOVE.L (A7),D0
- | 0008 6100 0000-XX.1 BSR.W @bar
- | 000C 584F ADDQ.W #4,A7
- | 000E 4E75 RTS
- ------------------------------
-
- The two first assembler instructions shows the problem: the compiler allocates
- room for four bytes on the stack and promptly writes eight bytes to the
- location, thus owerwriting the return address for the procedure.
-
- This one might actually be less of a bug than the two other, because I think
- the code in the example is broken. By providing a prototype for foo() and then
- defining it old-style with a float argument, I believe it invokes undefined
- behaviour. However, I still think it is naughty of the compiler to overwrite
- the return address ;-).
-
-
- --
- Per Liboriussen
- liborius@daimi.aau.dk
-
-